#include "EditerLayer.h"
#include "imgui.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "GLShader.h"
#include "Application.h"
namespace HS {
	EditorLayer::EditorLayer()
		: Layer("EditorLayer"), m_Camera(-1.6f, 1.6f, -0.9f, 0.9f)
	{
		
	}

	void EditorLayer::OnAttach()
	{
		m_VertexArray = VertexArray::Create();
		FramebufferSpecification fbSpec;
		fbSpec.Width = 1280;
		fbSpec.Height = 720;
		m_FrameBuffer = Framebuffer::Create(fbSpec);
	
		// Square
		m_SqurVAO = VertexArray::Create();
		float verticesSquare[] = {
			-0.75f, -0.75f, 0.0f, 0.0f,0.0f,
			 0.75f, -0.75f, 0.0f, 1.0f,0.0f,
			 0.75f,  0.75f, 0.0f, 1.0f,1.0f,
			-0.75f,  0.75f, 0.0f, 0.0f,1.0f
		};
		std::shared_ptr<VertexBuffer> squareVBO = VertexBuffer::Create(verticesSquare, sizeof(verticesSquare));
		BufferLayout squareLayout = {
			{ ShaderDataType::Float3, "a_Pos" },
			{ ShaderDataType::Float2, "a_TexCoord" }
		};
		squareVBO->SetLayout(squareLayout);
		m_SqurVAO->SetVertexBuffer(squareVBO);

		unsigned int squareIndex[6] = { 0,1,2,2,3,0 };
		std::shared_ptr<IndexBuffer> squareIBO;
		squareIBO  = IndexBuffer::Create(squareIndex, sizeof(squareIndex) / sizeof(uint32_t));
		m_SqurVAO->SetIndexBuffer(squareIBO);

		auto suqrShader = shaderLibrary.Load("Assets/Shaders/Texture.glsl");
		m_Texture = Texture2D::Create("Assets/Textures/Checkerboard.png");
		m_Texture1 = Texture2D::Create("Assets/Textures/moss.png");
		std::dynamic_pointer_cast<GLShader>(suqrShader)->Bind();
		std::dynamic_pointer_cast<GLShader>(suqrShader)->SetInt("u_Tex", 0);
	}

	void EditorLayer::OnDetach()
	{

	}

	void EditorLayer::OnUpdate(Timestep ts)
	{
		m_FrameBuffer->Bind();
		RenderCommand::SetClearColor({ 0.1,0.3,0.1,1 });
		RenderCommand::Clear();

		m_Camera.SetPosition({0,0,0});
		Render::BeginScene(m_Camera);
		{
			auto textureShader = shaderLibrary.Get("Texture");
			m_Texture->Bind();
			Render::Submit(textureShader, m_SqurVAO);

			m_Texture1->Bind();
			Render::Submit(textureShader, m_SqurVAO);
		}
		Render::EndScene();
		m_FrameBuffer->Unbind();
	}

	void EditorLayer::OnImGuiRender()
	{
#pragma region DockSpace
		static bool dockSpaceOpen = true;
		static bool opt_fullscreen = true;
		static bool opt_padding = false;
		static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;

		// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
		// because it would be confusing to have two docking targets within each others.
		ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
		if (opt_fullscreen)
		{
			const ImGuiViewport* viewport = ImGui::GetMainViewport();
			ImGui::SetNextWindowPos(viewport->WorkPos);
			ImGui::SetNextWindowSize(viewport->WorkSize);
			ImGui::SetNextWindowViewport(viewport->ID);
			window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
			window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
		}
		else
		{
			dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
		}

		// When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
		// and handle the pass-thru hole, so we ask Begin() to not render a background.
		if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
			window_flags |= ImGuiWindowFlags_NoBackground;

		// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
		// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
		// all active windows docked into it will lose their parent and become undocked.
		// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
		// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.

		ImGui::Begin("DockSpace Demo", &dockSpaceOpen, window_flags);

		// DockSpace
		ImGuiIO& io = ImGui::GetIO();
		if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
		{
			ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
			ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
		}

		if (ImGui::BeginMenuBar())
		{
			if (ImGui::BeginMenu("File"))
			{
				// Disabling fullscreen would allow the window to be moved to the front of other windows,
				// which we can't undo at the moment without finer window depth/z control.
				if (ImGui::MenuItem("Quit"))
				{
					Application::Get().Close();
				}
				ImGui::EndMenu();
			}
			ImGui::EndMenuBar();
		}

		ImGui::End();
#pragma endregion

		ImGui::Begin("Settings");
		ImGui::Image((ImTextureID)m_Texture->GetRendererID(), ImVec2(300.0f, 300.0f), ImVec2(0,1),ImVec2(1,0));
		ImGui::End();


		ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
		ImGui::Begin("Scene");
		m_IsViewPortFocus = ImGui::IsWindowFocused();
		m_IsViewPortHover = ImGui::IsWindowHovered();
		Application::Get().GetImGuiLayer()->BlockEvents(!m_IsViewPortFocus || !m_IsViewPortHover);
		/*LOGINFO("Is window Foucs : {0}",ImGui::IsWindowFocused());
		LOGINFO("Is window Hover : {0}", ImGui::IsWindowHovered());*/

		ImVec2 viewportSize = ImGui::GetContentRegionAvail();
		if (m_ViewPortSize != *((glm::vec2*)&viewportSize))
		{
			m_FrameBuffer->Resize((uint32_t)m_ViewPortSize.x,(uint32_t)m_ViewPortSize.y);
			m_ViewPortSize = { viewportSize.x, viewportSize.y };
		}
		//LOGWARN("ViewPort Size : {0} {1}", viewportSize.x, viewportSize.y);
		ImGui::Image((ImTextureID)m_FrameBuffer->GetColorAttachmentRendererID(), ImVec2(m_ViewPortSize.x, m_ViewPortSize.y), ImVec2(0, 1), ImVec2(1, 0));
		ImGui::End();
		ImGui::PopStyleVar();
	}

	void EditorLayer::OnEvent(Event& e)
	{
		
	}
}

